﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Effects;

namespace D3crft.Windows.UserControls {

    public partial class ucTextBox : UserControl {

        public event TextChangedEventHandler evTextChanged;
        public event KeyEventHandler evKeyDown;
        public event KeyEventHandler evKeyUp;

        TextBox oRoot;
        Grid oRootGrid;
        Border oBorder;
        TextBox oTextBox;
        DropShadowEffect oShadow;

        private string[] sLastText;
        private int[] iLastSelectionStart;
        private int[] iLastSelectionLength;

        // ####################################################
        // #####    Class Initialization
        // ####################################################
        #region Class Initialization

        public ucTextBox() {
            do_Initialize();
            do_Preset();
        }

        private void do_Initialize() {
            InitializeComponent();
            sLastText = new string[2];
            iLastSelectionStart = new int[2];
            iLastSelectionLength = new int[2];
        }

        private void do_Preset() {
            oRoot = FindName("Root") as TextBox;
            oRootGrid = FindName("RootGrid") as Grid;
            oBorder = FindName("Border") as Border;
            oTextBox = FindName("TextBox") as TextBox;
            oShadow = FindName("Shadow") as DropShadowEffect;

            this.Loaded += new RoutedEventHandler(ev_Object_Loaded);
            oTextBox.GotFocus += new RoutedEventHandler(ev_oTextBox_GotFocus);
            oTextBox.LostFocus += new RoutedEventHandler(ev_oTextBox_LostFocus);
            oTextBox.TextChanged += new TextChangedEventHandler(ev_oTextBox_TextChanged);
            oTextBox.SelectionChanged += new RoutedEventHandler(ev_oTextBox_SelectionChanged);
            oTextBox.KeyDown += new KeyEventHandler(ev_oTextBox_KeyDown);
            oTextBox.KeyUp += new KeyEventHandler(ev_oTextBox_KeyUp);
        }

        #endregion

        // ####################################################
        // #####    Public Acccess
        // ####################################################
        #region Public Acccess

        public string Text {
            get { return oTextBox.Text; }
            set { oTextBox.Text = value; }
        }

        new public bool Focus() {
            return oTextBox.Focus();
        }

        public void RevertLastText() {
            oTextBox.TextChanged -= ev_oTextBox_TextChanged;
            oTextBox.SelectionChanged -= ev_oTextBox_SelectionChanged;
            oTextBox.Text = sLastText[1];
            oTextBox.SelectionStart = iLastSelectionStart[1];
            oTextBox.SelectionLength = iLastSelectionLength[1];
            sLastText[0] = sLastText[1];
            iLastSelectionStart[0] = iLastSelectionStart[1];
            iLastSelectionLength[0] = iLastSelectionLength[1];
            oTextBox.TextChanged += ev_oTextBox_TextChanged;
            oTextBox.SelectionChanged += ev_oTextBox_SelectionChanged;
            if (evTextChanged != null) evTextChanged(this, null);
        }

        #endregion

        // ####################################################
        // #####    Events
        // ####################################################
        #region Events

        private void ev_oTextBox_GotFocus(object sender, EventArgs ea) {
            oBorder.BorderBrush = Application.Current.FindResource("Brush_BlueHighlightedBorder") as Brush;
            oShadow.Color = (Color)Application.Current.FindResource("Color_BlueHighlightedBorder");
            oShadow.ShadowDepth = 1.75;
            oShadow.Opacity = 0.67;
        }

        private void ev_oTextBox_LostFocus(object sender, EventArgs ea) {
            oBorder.BorderBrush = Application.Current.FindResource("Brush_Border") as Brush;
            oShadow.Color = (Color)Application.Current.FindResource("Color_Border");
            oShadow.ShadowDepth = 1.0;
            oShadow.Opacity = 0.5;
        }

        private void ev_oTextBox_TextChanged(object sender, TextChangedEventArgs ea) {
            sLastText[1] = sLastText[0];
            iLastSelectionStart[1] = iLastSelectionStart[0];
            iLastSelectionLength[1] = iLastSelectionLength[0];
            sLastText[0] = oTextBox.Text;
            iLastSelectionStart[0] = oTextBox.SelectionStart;
            iLastSelectionLength[0] = oTextBox.SelectionLength;
            if (evTextChanged != null) evTextChanged(this, ea);
        }

        private void ev_oTextBox_SelectionChanged(object sender, RoutedEventArgs ea) {
            iLastSelectionStart[1] = oTextBox.SelectionStart;
            iLastSelectionLength[1] = oTextBox.SelectionLength;
            iLastSelectionStart[0] = oTextBox.SelectionStart;
            iLastSelectionLength[0] = oTextBox.SelectionLength;
        }

        private void ev_oTextBox_KeyDown(object sender, KeyEventArgs ea) {
            if (evKeyDown != null) evKeyDown(sender, ea);
        }

        private void ev_oTextBox_KeyUp(object sender, KeyEventArgs ea) {
            if (evKeyUp != null) evKeyUp(sender, ea);
        }

        private void ev_Object_Loaded(object sender, EventArgs ea) {
            (FindName("RootGrid") as Grid).Width = Root.Width;
        }

        #endregion
    }
}
